// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License.html/free.pdf

#ifndef MGCAPPLICATION_H
#define MGCAPPLICATION_H

#include <MgcCore.pkg>
#include <MgcEngine.pkg>

class MgcCommand;

namespace Mgc
{
	class MgcApplication
	{
	public:
		// abstract base class
		virtual ~MgcApplication ();

		// derived classes implement these as needed
		virtual bool OnInitialize ();
		virtual void OnTerminate ();
		virtual void OnReshape (int iWidth, int iHeight);
		virtual void OnDisplay ();
		virtual void OnIdle ();
		virtual void OnKeyPress (unsigned char ucKey, int iX, int iY);
		virtual void OnKeyDown (int iKey);
		virtual void OnKeyUp (int iKey);
		virtual void OnSpecialKeyPress (int iKey, int iX, int iY);
		virtual void OnSpecialKeyDown (int iKey);
		virtual void OnSpecialKeyUp (int iKey);
		virtual void OnMousePress (int iButton, int iState, int iX, int iY);
		virtual void OnMotion (int iX, int iY);
		virtual void OnPassiveMotion (int iX, int iY);

		// turret-based camera motion
		void SetTurretAxes ();  // use camera frame
		void SetTurretAxes (const MgcVector3& rkLeft, const MgcVector3& rkUp,
			const MgcVector3& rkDirection);

		// performance measurements
		static MgcReal GetTimeInSeconds ();
		void ResetTime ();
		void MeasureTime ();
		void UpdateClicks ();
		void DrawFrameRate (int iX, int iY);

		// access to the unique application object
		static MgcApplication* GetApplication ();

		// access to members set by constructor
		static char* GetWindowTitle ();
		static int GetWidth ();
		static int GetHeight ();
		static const MgcColor& GetBackgroundColor ();

		// access for initialization/termination
		static void SetCommand (MgcCommand* pkCommand);
		static MgcCommand* GetCommand ();
		static void SetWindowID (int iWindowID);
		static int GetWindowID ();
		static void SetRenderer (MgcRenderer* pkRenderer);
		static void SetCamera (MgcCamera* pkCamera);
		void RequestTermination ();

		// keyboard bindings
		static const int KEY_ESCAPE;
		static const int KEY_LEFT_ARROW;
		static const int KEY_RIGHT_ARROW;
		static const int KEY_UP_ARROW;
		static const int KEY_DOWN_ARROW;
		static const int KEY_HOME;
		static const int KEY_END;
		static const int KEY_PAGE_UP;
		static const int KEY_PAGE_DOWN;
		static const int KEY_INSERT;
		static const int KEY_DELETE;
		static const int KEY_F1;
		static const int KEY_F2;
		static const int KEY_F3;
		static const int KEY_F4;
		static const int KEY_F5;
		static const int KEY_F6;
		static const int KEY_F7;
		static const int KEY_F8;
		static const int KEY_F9;
		static const int KEY_F10;
		static const int KEY_F11;
		static const int KEY_F12;

		// mouse bindings
		static const int MGC_MOUSE_LEFT_BUTTON;
		static const int MGC_MOUSE_MIDDLE_BUTTON;
		static const int MGC_MOUSE_RIGHT_BUTTON;
		static const int MOUSE_UP;
		static const int MOUSE_DOWN;

	protected:
		// construction and destruction
		MgcApplication (char* acWindowTitle, int iWidth, int iHeight,
			const MgcColor& rkBackgroundColor);

		// turret-based camera motion
		virtual void MoveCamera ();
		virtual void MoveForward ();
		virtual void MoveBackward ();
		virtual void MoveUp ();
		virtual void MoveDown ();
		virtual void TurnLeft ();
		virtual void TurnRight ();
		virtual void LookUp ();
		virtual void LookDown ();

		bool m_bTurretActive;
		MgcVector3 m_akAxis[3];
		MgcReal m_fTrnSpeed;
		MgcReal m_fRotSpeed;
		bool m_bUArrowPressed;
		bool m_bDArrowPressed;
		bool m_bLArrowPressed;
		bool m_bRArrowPressed;
		bool m_bPgUpPressed;
		bool m_bPgDnPressed;
		bool m_bHomePressed;
		bool m_bEndPressed;

		// performance measurements
		MgcReal m_fLastTime, m_fAccumulatedTime, m_fFrameRate;
		int m_iClicks, m_iTimer, m_iMaxTimer;

		// There can be only one.
		static MgcApplication* ms_pkApplication;
		static MgcCommand* ms_pkCommand;
		static char* ms_acWindowTitle;
		static int ms_iWindowID, ms_iWidth, ms_iHeight;
		static MgcColor ms_kBackgroundColor;
		static MgcRendererPtr ms_spkRenderer;
		static MgcCameraPtr ms_spkCamera;
	};

	#include "MgcApplication.inl"
}

#endif
